package com.beidu.lottery.call.result;

import com.beidu.lottery.call.errorcode.CommonCode;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;

import java.io.Serializable;
import java.util.Objects;

/**
 * 接口返回对象封装
 */
@Getter
@SuppressWarnings("unused")
public class Res<T> implements Serializable, Cloneable {

    private static final long serialVersionUID = 1L;

    /**
     * 状态码
     */
    @ApiModelProperty(value = "状态码")
    private String code;

    /**
     * 消息提示
     */
    @ApiModelProperty(value = "消息提示")
    private String msg;

    /**
     * 响应数据
     */
    @ApiModelProperty(value = "响应数据")
    @JsonProperty("data")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private T data;

    public Res() {
        this.msg = CommonCode.SUCCESS.getMsg();
        this.code = CommonCode.SUCCESS.getCode();
    }

    public Res(T data, String code, String msg) {
        this.data = data;
        this.msg = msg;
        this.code = code;
    }

    public static <T> Res<T> with(String code) {
        Res<T> res = new Res<>();
        res.code = code;
        res.msg = Objects.requireNonNull(CommonCode.findByCode(code)).getMsg();
        return res;
    }

    public static <T> Res<T> with(String code, String msg) {
        return new Res<>(null, code, msg);
    }

    public static <T> Res<T> error() {
        return with(CommonCode.ERROR.getCode());
    }

    public static <T> Res<T> fail(String msg) {
        return new Res<>(null, "500", msg);
    }

    public static <T> Res<T> success() {
        return with(CommonCode.SUCCESS.getCode());
    }

    public static <T> Res<T> success(T data) {
        return new Res<>(data, CommonCode.SUCCESS.getCode(), CommonCode.SUCCESS.getMsg());
    }

    public static <T> Res<T> busy() {
        return Res.with(CommonCode.BUSY.getCode(), CommonCode.BUSY.getMsg());
    }

    public static <T> Res<T> rateLimiter() {
        return Res.with(CommonCode.RATE_LIMITER.getCode(), CommonCode.RATE_LIMITER.getMsg());
    }

    public Res<T> msg(String msg) {
        this.msg = msg;
        this.code = CommonCode.SUCCESS.getCode();
        return this;
    }

    public Res<T> data(T data) {
        this.data = data;
        this.msg = CommonCode.SUCCESS.getMsg();
        this.code = CommonCode.SUCCESS.getCode();
        return this;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public static void isTrue(boolean condition, String exceptionMsg) {
        if (!condition) {
            throw new ResException("400", exceptionMsg);
        }
    }

    public static void isFalse(boolean condition, String exceptionMsg) {
        if (!condition) {
            throw new ResException("400", exceptionMsg);
        }
    }

}
